package com.iot08.admin.service;

import com.iot08.admin.service.page.PageableImpl;
import com.iot08.common.constant.Const;
import com.iot08.common.entity.admin.Channel;
import com.iot08.common.entity.admin.ChannelAffiliation;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.common.response.Response;
import com.iot08.common.service.base.BaseAdminService;
import com.iot08.common.utils.DateUtil;
import com.iot08.admin.service.page.PageVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;


/**
 * @version 1.0
 * @author: Rock
 * @Description:
 * @time: 2020/8/13 18:40
 */
@Service
public class ChannelService extends BaseAdminService<Channel> {

    @Resource
    private ChannelAffiliationService channelAffiliationService;
    @Resource
    private DeviceService deviceService;
    @Resource
    private OperationService operationService;
    @Resource
    private ChannelAreaService channelAreaService;

    public List<Channel> findAll(){
        // 查询所有 deleted==0
        return this.find(new Query().addCriteria(Criteria.where("deleted").is(0)));
    }
    /**
     * @param [pageNum, pageSize]
     * @Description: 渠道列表
     * @time: 2020/8/14 9:40
     * @author: Rock
     * @version 1.0
     */
    public Page<Channel> list(PageVO page, Integer status, SysUser user) {
        PageableImpl pageable = new PageableImpl();
        page.setSort(Sort.by(Order.desc("create_time")));
        pageable.setPage(page);

        Criteria criteria = new Criteria().and("deleted").is(0);
        if (StringUtils.isNotEmpty(page.getSearchValue())) {
            criteria.and("name").regex(".*?" + page.getSearchValue() + ".*?", "i");
        }
        if (status != null) {
            criteria.and("status").is(status);
        }
        if (user.getType() == Const.CHANNELUSER_TYPE) {
            criteria.and("channel_code").in(user.getChannelAff().getChannelCodes());
        }

        Query query = new Query().addCriteria(criteria);
        long count = this.count(query);
        page.setTotalResult((int) count);
        List<Channel> list = this.find(query.with(pageable));
        Page<Channel> result = new PageImpl<Channel>(list, pageable, count);
        return result;
    }

    /**
     * @param [id]
     * @return void
     * @Description: 删除
     * @time: 2020/8/14 18:58
     * @author: Rock
     * @version 1.0
     */
    public Response<Object> updateDel(String id, SysUser user, String ip) {
        List<ChannelAffiliation> list = channelAffiliationService.listByChannelIds(id);
        if (list != null && list.size() > 0) {
            return Response.failedResponse("存在渠道归属引用该渠道，无法删除");
        }
        Channel channel = this.findById(id);
        if (channel != null) {
            if (channel.getImportNum() != null && channel.getImportNum() > 0) {
                return Response.failedResponse("存在设备引用该渠道，无法删除");
            }
            Update update = new Update();
            update.set("deleted", 1);
            update.set("update_time", new Date());
            this.updateById(id, update);
            operationService.add(user, ip, "渠道商列表", "删除", "删除渠道商 ：" + channel.getName());
            return Response.successResponse();
        }
        return Response.failedResponse("渠道不存在");
    }

    /**
     * @param [id, status]
     * @Description: 更新状态
     * @time: 2020/8/17 10:03
     * @author: Rock
     * @version 1.0
     */
    public void updateStatus(String id, Integer status, SysUser user, String ip) {
        Update update = new Update();
        update.set("status", status);
        update.set("update_time", new Date());
        this.updateById(id, update);
        Channel channel = this.findById(id);
        operationService.add(user, ip, "渠道商列表", "编辑",
                "更新渠道商 :" + channel.getName() + " 的状态为：" + (status == 0 ? "禁用" : "启用"));
    }

    /**
     * @Description: 保存
     * @time: 2020/8/17 17:29
     * @author: Rock
     * @version 1.0
     */
    public void save(Channel channel, SysUser user, String ip) {
        if (channel != null) {
            String id = DateUtil.dateToStr(new Date(), DateUtil.FORMAT_2);
            channel.setId(id);
            channel.setChannelCode(Long.parseLong(id));
            channel.setDeleted(0);
            channel.setCreateTime(new Date());
            this.save(channel);
            //添加渠道区域
            channelAreaService.addLevel_1(Long.parseLong(id), channel.getName(), user, ip);
            operationService.add(user, ip, "渠道商列表", "添加", "添加渠道商 ：" + channel.getName());
        }
    }

    /**
     * @param [channel]
     * @Description: 更新
     * @time: 2020/8/18 10:41
     * @author: Rock
     * @version 1.0
     */
    public void update(Channel channel, SysUser user, String ip) {
        if (channel != null) {
            Update update = new Update();
            update.set("status", channel.getStatus());
            update.set("shift_limit", channel.getShiftLimit());
            update.set("unbundling", channel.getUnbundling());
            update.set("canCheckPosition", channel.getCanCheckPosition());
            update.set("checkDActinoStatus", channel.getCheckDActinoStatus());
            update.set("account", channel.getAccount());
            update.set("password", channel.getPassword());
            update.set("update_time", new Date());
            this.updateById(channel.getId(), update);
            operationService.add(user, ip, "渠道商列表", "编辑", "编辑渠道商： " + channel.getName());
        }
    }

    /**
     * @Description: 获取当前用户全部渠道
     * @time: 2020/8/18 19:05
     * @author: Rock
     * @version 1.0
     */
    public List<Channel> listAll(SysUser user) {
        Criteria criteria = Criteria.where("deleted").is(0);
        if (user.getType() == Const.CHANNELUSER_TYPE) {
            if (user.getChannelArea() != null && user.getChannelArea().getLevel() != null
                    && user.getChannelArea().getLevel() > 1) {
                criteria.and("channel_code").is(user.getChannelArea().getChannelCode());
            } else {
                criteria.and("channel_code").in(user.getChannelAff().getChannelCodes());
            }
        }
        return this.find(new Query(criteria));
    }

    /**
     * @param [ids]
     * @time: 2020/8/31 16:52
     * @author: Rock
     * @version 1.0
     */
    public List<Channel> getByIds(List<String> ids) {
        Query query = new Query(Criteria.where("_id").in(ids).and("deleted").is(0));
        return this.find(query);
    }

    /**
     * @param [id, name, channelCode, account]
     * @time: 2020/9/3 15:13
     * @author: Rock
     * @version 1.0
     */
    public String check(String id, String name, String account) {
        Channel channel = getByName(name);
        if (channel != null) {
            if (StringUtils.isEmpty(id) || !id.equals(channel.getId())) {
                return "渠道名称已存在！";
            }
        }
        channel = getByAccount(account);
        if (channel != null) {
            if (StringUtils.isEmpty(id) || !id.equals(channel.getId())) {
                return "渠道登录账号已存在！";
            }
        }
        return "";
    }

    /**
     * @param [name]
     * @time: 2020/9/3 15:09
     * @author: Rock
     * @version 1.0
     */
    private Channel getByName(String name) {
        Query query = new Query(Criteria.where("deleted").is(0).and("name").is(name));
        return this.findOne(query);
    }

    /**
     * @param [channelCode]
     * @time: 2020/9/3 15:10
     * @author: Rock
     * @version 1.0
     */
    public Channel getByChannelCode(Long channelCode) {
        Query query = new Query(Criteria.where("deleted").is(0).and("channel_code").is(channelCode));
        return this.findOne(query);
    }

    /**
     * @param [account]
     * @time: 2020/9/3 15:10
     * @author: Rock
     * @version 1.0
     */
    private Channel getByAccount(String account) {
        Query query = new Query(Criteria.where("deleted").is(0).and("account").is(account));
        return this.findOne(query);
    }

    /**
     * @param channelCode
     * @time: 2020/10/28 18:00
     * @author: Rock
     * @version 1.0
     */
    /*public void updateNum(Long channelCode){
        Query query = new Query(Criteria.where("channel_code").is(channelCode).and("deleted").is(0));
        Channel channel = mongoTemplate.findOne(query, Channel.class);
        if(channel != null) {
            Update update = new Update();
            update.set("import_num", (int)deviceService.countByAgent(channelCode));
            update.set("active_num", (int)deviceService.countActiveNumByAgent(channelCode));
            mongoTemplate.updateFirst(query, update, Channel.class);
        }
    }*/

    /**
     * 重置密码
     *
     * @param id
     * @time: 2020/10/13 18:04
     * @author: Rock
     * @version 1.0
     */
    public Response<Object> resetPwd(String id, SysUser user, String ip) {
        Update update = new Update();
        update.set("password", "123456");
        update.set("update_time", new Date());
        this.updateById(id, update);
        Channel channel = this.findById(id);
        operationService.add(user, ip, "渠道商列表", "编辑", "重置渠道商密码： " + channel.getName());
        return Response.successResponse();
    }

    /**
     * @time: 2020/9/8 11:47
     * @author: Rock
     * @version 1.0
     */
    public void updateNumJop() {
        Query query = new Query(Criteria.where("deleted").is(0));
        query.fields().include("channel_code");
        List<Channel> channels = this.find(query);
        for (Channel channel : channels) {
            if (channel == null || channel.getChannelCode() == null) {
                continue;
            }
            long importNum = deviceService.countByAgent(channel.getChannelCode());
            long activeNum = deviceService.countActiveNumByAgent(channel.getChannelCode());
            Update update = new Update().set("import_num", importNum).set("active_num", activeNum);
            this.update(new Query(Criteria.where("channel_code").is(channel.getChannelCode()).and("deleted").is(0)), update);
        }
    }

}
